﻿/*
 * SpatialDbCommand.FeatureMetadata
 * 
 * initial implementation : 20.9.2008
 *
 * Copyright (c) Adam Sida, asida@centrum.cz.
 * All rights reserved.
 * 
 * for license see Petra.Gis.License.txt
 */
using System;
//using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
//using System.Windows.Markup;
//using Petra.Gis.Geometry.Support;
using Petra.Gis.DataServices.Metadata;
//using Petra.Gis.ReferenceSystemServices;


namespace Petra.Gis.DataServices
{
  public abstract partial class SpatialDbCommand : DbCommand
  {


    FeatureMetadata _metadata;

    /// <summary>
    /// returns original FeatureMetadata as maintained in data source
    /// </summary>
    /// <returns>default FeatureMetadata</returns>
    public FeatureMetadata Metadata
    {
      get
      {
        if(_metadata == null)
        _metadata = getFeatureMetadata();

        return _metadata;
      }

      protected set 
      {
        _metadata = value;
      }
    }
    //{ get; protected set; }



    /// <summary>
    /// when command combines data from various features in data source (for example in sql)
    /// this method enables to select which FeatureMetadata will be used on output as default.
    /// When complex query occurrs (join), there might be problem automatically recongnize which metadata use.
    /// </summary>
    /// <param name="forceMetadataByFeatureName">forces this object to use metadata from another feature</param>
    /// <returns>FeatureMetadata of feature given by name</returns>
    public void ForceFeatureMetadata(string forceMetadataByFeatureName)
    {
      Metadata = forceFeatureMetadata(forceMetadataByFeatureName);
    }


    
    
    /// <summary>
    /// when command combines data from various features in data source (for example in sql)
    /// this method enables to select which FeatureMetadata will be used on output as default.
    /// When complex query occurrs (join), there might be problem automatically recongnize which metadata use.
    /// </summary>
    /// <param name="forceMetadataByFeatureName">forces this object to use metadata from another feature</param>
    /// <returns>FeatureMetadata of feature given by name</returns>
    protected abstract FeatureMetadata forceFeatureMetadata(string forceMetadataByFeatureName);





    /// <summary>
    /// get metadata by full feature qualifier. This method is available only for System.Data data sources.
    /// </summary>
    /// <returns>FeatureMetadata for this object or null when not found</returns>
    protected abstract FeatureMetadata getFeatureMetadata();





    /// <summary>
    /// get metadata by full feature qualifier. This method is available only for System.Data data sources,
    /// where usually catalog and schema exists (sql server, oracle, DB2,...).
    /// </summary>
    /// <param name="catalog">catalog name in data source</param>
    /// <param name="schema">schema in catalog (empty string can be supplied when no schema available)</param>
    /// <param name="featureName">feature name to use its metadata</param>
    /// <returns>FeatureMetadata for given object specified by catalog, schema, and feature name or null when not found</returns>
    protected abstract FeatureMetadata getFeatureMetadata(string catalog, string schema, string featureName);




    protected virtual FeatureQualifier parseFeatureQualifierFromLongName(string fullTableName)
    {
      string[] vals = fullTableName.Split('.');
      if (vals.Length < 1 || vals.Length > 3)
        throw new ArgumentException("invalid table qualifier " + fullTableName);

      FeatureQualifier result = new FeatureQualifier();

      if (vals.Length > 2)
      {
        result.Schema = vals[vals.Length - 2];
        result.Catalog = vals[vals.Length - 3];
      }
      else if (vals.Length > 1)
        result.Schema = vals[vals.Length - 2];

      result.Name = vals[vals.Length - 1];

      return result;
    }





    //protected virtual void prepareSpatialMetadata()
    //{

    //  if (this.CommandText == "" || this.CommandText == null)
    //    return;

    //  if (this.Connection.State != ConnectionState.Open)
    //    return;

    //  // if text contains no whitespaces
    //  // if (value.Trim().IndexOf(" ") < 1)
    //  //if (CommandType == CommandType.TableDirect)
    //  //  getSpatialMetadataFromTableName(value);
    //  //else if (CommandType == CommandType.Text)
    //  //  getSpatialMetadataFromSqlText(value);
    //  //else
    //  //  getSpatialMetadataFromRemark(value);


    //  // if command is direct table command, get spatialmetadata by table name
    //  if (this.CommandType == CommandType.TableDirect)
    //  {
    //    // try parse valid Feature name
    //    // expected value is catalog.schema.featureName
    //    string[] vals = this.CommandText.Split('.');
    //    if (vals.Length < 1 || vals.Length > 3)
    //      throw new ArgumentException("invalid table qualifier " + this.CommandText);

    //    string schema = "";
    //    string owner = "";
    //    string tablename = "";

    //    if (vals.Length > 2)
    //    {
    //      owner = vals[vals.Length - 2];
    //      schema = vals[vals.Length - 3];
    //    }
    //    else if (vals.Length > 1)
    //      owner = vals[vals.Length - 2];

    //    tablename = vals[vals.Length - 1];

    //    _metadata = GetFeatureMetadata(schema, owner, tablename);

    //    //getSpatialMetadataFromTableName(this.CommandText);
    //    return;
    //  }
    //  else
    //    throw new ArgumentException("unsupported commandType " + this.CommandType.ToString());
    //  // ok, command contains 'some' text try to parse this text and get metadata
    //  //{
    //  //  getSpatialMetadataFromSqlText(this.CommandText);

    //  //  //if (!this.Extensions.ContainsKey("FeatureMetadata"))
    //  //  //if (_metadata == null)
    //  //  //  getSpatialMetadataFromRemark(this.CommandText);
    //  //}

    //}



  }
}
